package org.infodavid.common.model.impl;

import java.util.Collection;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.infodavid.common.persistence.IBasicDataObject;

/**
 * The Class AbstractBasicDataObjectImpl.
 */
public abstract class AbstractBasicDataObjectImpl implements IBasicDataObject {

  /** serialVersionUID. */
  private static final long serialVersionUID = 88100362653087511L;

  /** The Constant log. */
  protected static final Log LOGGER = LogFactory.getLog(AbstractBasicDataObjectImpl.class);

  /** The modificationTrackingEnabled variable. */
  private static boolean modificationTrackingEnabled = false;

  /**
   * Equals.
   * @param obj1 the obj1
   * @param obj2 the obj2
   * @return true, if successful
   */
  public static boolean equals(final Object obj1, final Object obj2) {
    final boolean result;

    if (obj1 == obj2) {
      result = true;
    }
    else if (obj1 == null || obj2 == null) {
      result = false;
    }
    else if (obj1 instanceof Collection) {
      result = false;
    }
    else {
      result = obj1.equals(obj2);
    }

    return result;
  }

  /** The modified. */
  private boolean modified;

  /**
   * constructor.
   * @throws Exception the exception
   */
  protected AbstractBasicDataObjectImpl() throws Exception {
    super();

    init();

    if (LOGGER.isTraceEnabled()) {
      LOGGER.trace("Calling default constructor for class : " + getClass().getName());
    }
  }

  /*
   * (non-Javadoc)
   * @see org.infodavid.common.model.IBasicDataObject#init()
   */
  @Override
  public void init() throws Exception {
    if (LOGGER.isTraceEnabled()) {
      LOGGER.trace("Initializing the instance of : " + getClass().getName());
    }

    modified = true;
  }

  /*
   * (non-Javadoc)
   * @see org.infodavid.common.model.IBasicDataObject#isModified()
   */
  @Override
  public boolean isModified() {
    return modified;
  }

  /*
   * (non-Javadoc)
   * @see org.infodavid.common.model.IBasicDataObject#markModified(java.lang.String)
   */
  @Override
  public void markModified(final String property) {
    if (isModificationTrackingEnabled()) {
      modified = true;

      if (LOGGER.isTraceEnabled()) {
        LOGGER.trace("Property " + property + " changed, object as modified : " + toString());
      }
    }
  }

  /*
   * (non-Javadoc)
   * @see java.lang.Object#toString()
   */
  @Override
  public String toString() {
    final StringBuffer buffer = new StringBuffer(super.toString());

    toString(buffer);
    buffer.append(')');

    return buffer.toString();
  }

  /**
   * Mark stored.
   */
  protected void markStored() {
    modified = false;

    if (LOGGER.isTraceEnabled()) {
      LOGGER.trace("Object marked as stored : " + toString());
    }
  }

  /*
   * (non-Javadoc)
   * @see org.infodavid.common.model.IBasicDataObject#isModificationTrackingEnabled()
   */
  @Override
  public boolean isModificationTrackingEnabled() {
    return modificationTrackingEnabled;
  }

  /*
   * (non-Javadoc)
   * @see org.infodavid.common.model.IBasicDataObject#setModificationTrackingEnabled (boolean)
   */
  @Override
  public void setModificationTrackingEnabled(final boolean flag) {
    if (!modificationTrackingEnabled && flag) {
      modified = true;
    }

    modificationTrackingEnabled = flag;
  }

  /**
   * To string.
   * @param buffer the buffer
   * @return the string representation
   */
  protected StringBuffer toString(final StringBuffer buffer) {
    buffer.append(" (");
    buffer.append("isModified = ").append(isModified());

    return buffer;
  }
}
